import { onMounted, reactive } from "vue";
import { PD_22 } from "./beltParms/PD_22";
import { PD_22N } from "./beltParms/PD_22_N";
import { PD_31 } from "./beltParms/PD_31"
import { PD_42_1 } from "./beltParms/PD_42_1";
import { PD_42_2 } from "./beltParms/PD_42_2";
import { PD_42N } from "./beltParms/PD_42_N";
import { PD_52_1 } from "./beltParms/PD_52_1";
import { PD_52_2 } from "./beltParms/PD_52_2";  //5-2大巷二部皮带
import { PD_ZJ } from "./beltParms/PD_Main";  //主井皮带
import { PD_101 } from "./beltParms/PD_101";  //101皮带
import { PD_104_105 } from "./beltParms/PD_104_105";  //104,105皮带
import { PD_52N } from "./beltParms/PD_52_N";  //5-2 南1





// 定义一个响应式对象 act，用于存储PLC所有相关数据和状态
export const act = reactive({
  status: false,
  run: false,
  speed: 0,
  WebSockeetServer: false,    // 速度值
  PD_22,
  PD_22N,
  PD_31,
  PD_42_1,
  PD_42_2,
  PD_42N,
  PD_52_1,
  PD_52_2,//5-2大巷二部皮带
  PD_ZJ, //主井皮带
  PD_101,//101皮带
  PD_104_105,//104,105皮带
  PD_52N,  //5-2 南1
});

let ws;              // WebSocket连接实例
let intervalId;      // 定时器
const messageQueue: any[] = [];  // 客户端网页的消息队列，用于存储想服务器待发送的消息---such as装双色球的容器

/**
 * 读取WebSocket数据
 * @param {string} topic - 订阅的主题---每个页面/整个系统
 */
export function createWebSocket(topic) {
  // 如果已存在WebSocket连接，先关闭
  if (ws) {
    ws.close
  }

  // 一、创建新的WebSocket连接
  ws = new WebSocket("ws://10.23.20.103:12000/ws/");

  // 二、WebSocket连接成功后，向服务器发送消息
  ws.onopen = () => {
    console.log("WebSocket连接成功~~~");
    // 数据拼接————由于陈总服务器需要我传过去的格式为：{ topic: topic, action: "read"  }
    const sendtopic = { topic: topic }; // 设备主题格式: device::topic
    const sort = { action: "read" };    // 操作-读取

    // 开启定时器，每隔1秒发送读取请求，将消息加入消息队列
    intervalId = setInterval(() => {
      const msg = { ...sort, ...sendtopic }; // 合并消息
      // console.log('要加入消息队列，待传送的数据是：', msg);
      // 一个msg相当于一个小球--红球、黄球、篮球等待被送到服务器

      messageQueue.push(msg);// 将消息加入队列
    }, 5000);

    // 处理消息队列中的消息
    processMessageQueue();
  };
  /**
   * 处理消息队列中的消息
   */
  function processMessageQueue() {
    // 开启定时器，每100毫秒检查一次队列，将消息队列中的每一项，依次发给服务器
    setInterval(() => {
      // 当WebSocket已连接 且 队列中有消息
      if (ws && ws.readyState === WebSocket.OPEN && messageQueue.length > 0) {
        const message = messageQueue.shift(); // 取出队列中的第一个消息(备注：shift()用于移除数组的第一个元素，并返回该元素)
        ws.send(JSON.stringify(message));     // 发送消息----tip：连续调用多次 ws.send()，会自动排队
      } else if (messageQueue.length > 0) {
        // 队列中有消息，但是WebSocket还没有连接
        console.log("WebSocket未准备好，正在等待发送消息…");
      }
    }, 100); // 每100毫秒检查一次队列
  }




  /* 
      三、接收到webscoket返回的数据，并处理数据
   */
  ws.onmessage = (event) => {
    if (JSON.parse(event.data).length === 1 || JSON.parse(event.data)[0]?.Name === '"----TAG_COUNT-------------"') {
      return
    }
    // console.log('数据data', JSON.parse(event.data));
    try {
      const data = JSON.parse(event.data);
      // 判断是否为数组
      if (Array.isArray(data)) {
        ProcessDataArray(data); // 如果是数组，调用数组处理方法
      } else {
        ProcessDataNew(data);  // 否则调用单个数据处理方法
      }
    } catch (error) {
      console.error("接收webscoket消息报错：", error);
    }
  };

  /**
   * 三、（一）处理数组数据
   * @param {Array} alldataList - 数据数组 [{Name:"PD_52_1::PD_52_GEN::CtrlStop_DO",Value:"0",timestamp:"25-08-13 17:16:57"},.......,{},{},{},{}]
   */
  function ProcessDataArray(alldataList) {
    alldataList.forEach((item) => {
      ProcessDataNew(item); // 对数组中的每个元素，调用单个数据处理方法
    });
  }

  /**
   * 三、（二）处理单个数据
   * @param {Object} data - 单个的数据对象 {}
   */
  function ProcessDataNew(data) {
    // const path = data.Name.split("::"); // 分割路径（例子：micrologix1400::MicrologixT::M_N7_1）
    // 注：Name格式有两种：① "PD_52_1::PD_52_GEN::CtrlStop_DO"    ②"CXGMJ_31.communication_status"

    const path = data.Name.includes("::")
      ? data.Name.split("::")
      : data.Name.split(".");

    const normalizedValue = normalizeValue(data.Value); // (1)规范化值
    // console.log("获取数值",normalizedValue,"path",path)
    setValueIfExists(act, path, normalizedValue); // (2)设置值到act对象
  }

  /**
 * 三、（二）、(1)规范化值
 * @param {any} value - 需要规范化的值
 * @returns {any} 规范化后的值
 */
  function normalizeValue(value: any): any {
    if (value === 'True' || value === 'true') return true;   // 字符串'true'转为布尔值true
    if (value === 'False' || value === 'false') return false; // 字符串'false'转为布尔值false
    if (!isNaN(value) && typeof value === 'string') {
      return Number(value); // 数字字符串转为数值
    }
    return value; // 其他情况直接返回原值
  }
  /**
   * 三、（二）、(2)根据路径设置值（如果路径存在）
   * @param {Object} act - 目标对象
   * @param {Array} path - 路径数组
   * @param {any} value - 要设置的值
   */
  function setValueIfExists(obj: any, path: string[], value: any) {
    
    let current = obj;
    // 遍历path  
    // 1.（例子：处理 ['PD_52_1','PD_52_GEN','CtrlStop_DO'] ）---path中除了最后一个
    for (let i = 0; i < path.length - 1; i++) {
      if (!(path[i] in current)) {
        console.warn(
          `路径错误: 找不到属性 '${path.slice(0, i + 1).join(".")}'`
        );
        return; // 找不到对应路径，终止赋值
      }
      current = current[path[i]];
    }
    // 2.（例子：处理 'CtrlStop_DO'）---path中最后一个
    const lastKey = path[path.length - 1];

    if (!(lastKey in current)) {
      console.warn(`路径错误: 找不到属性 '${path.join(".")}'`);
      return;
    }
    // 找到了完整路径，赋值
    current[lastKey] = value;
    // console.log("找到",act)
  }



  /* tip：
      clearInterval() 用于清除 setInterval() 设置的---重复定时器
      clearTimeout()  用于清除 setTimeout()  设置的---一次性定时器 */

  // 四、WebSocket发生错误时的回调
  ws.onerror = (error) => {
    console.error("WebSocket报错:", error);
    clearInterval(intervalId); // 清除定时器
  };

  // 五、WebSocket连接关闭时的回调
  ws.onclose = () => {
    console.log("WebSocket连接已关闭，正在重试…");
    clearInterval(intervalId); // 清除定时器
    setTimeout(createWebSocket, 5000); // 5秒后重新连接WebSocket
  };


}



/**
 * 设备操作按钮--写入WebSocket数据
 */
export function sendDataFromButton(
  tag: string,
  value: string | number | boolean
) {
  console.log("-----设备操作写入数据-----")


  // 解析 tag: "act.AAA.BBB.CCC"
  const parts = tag.split(".");
  if (parts.length !== 4 || parts[0] !== "act") {
    console.error("Invalid tag format. Expected format: act.AAA.BBB.CCC");
    return;
  }
  const [_, AAA, BBB, CCC] = parts;
  const formattedTag = `ns=1;s=${AAA}::${BBB}::${CCC}`;

  // 构建写入数据（不再需要 data_type）
  const wvalue = [
    {
      tag: formattedTag,
      value: value.toString(),
    },
  ];
  /* 
    // 要写入的值数组
    var wvalue = [
      {
        "tag": "ns=1;s=micrologix1400::MicrologixT::M_N7_1",
        "value": "15",
        "data_type": "int16"
      },
      {
        "tag": "ns=1;s=micrologix1400::MicrologixT::M_F8_8",
        "value": "1.5",
        "data_type": "float"
      }
    ];
    */
  const btnMsg = {
    action: "write",
    data: wvalue,
  };

  messageQueue.push(btnMsg);  // 将按钮消息加入队列 
  console.log("Button: Added message to queue", btnMsg);
}
